import { v4 } from "uuid";
import { anyObject } from "../interface/commonType";

const tryToJSON = (value: any) => {
  return !value || !value["toJSON"] ? value : value.toJSON();
};
export abstract class BreezeClass<T extends anyObject> {
  // private json = {};
  name: string = '';
  uuid: string = v4();
  [key: string]: any;

  constructor(funClass?: { [key: string]: any }, json?: T) {
    if (json) {
      // this.json = json;
      Object.keys(json).forEach((key: string) => {
        const FunClass = funClass && funClass[key];
        if (FunClass && Array.isArray(json[key])) {
          this[key] = [];
          Object.keys(json[key]).forEach((item: any) => {
            this[key].push(new FunClass(json[key][item]));
          });
        } else if (FunClass) {
          this[key] = new FunClass(json[key]);
        } else {
          this[key] = key === 'uuid' && !json[key] ? v4() : json[key];
        }
      })
    }
  }

  toJson() {
    const keys = Object.keys(this);
    const json = {};
    keys.forEach(key => {
      if (Array.isArray(this[key])) {
        json[key] = this[key].map((_item: BreezeClass<T>) => {
          tryToJSON(_item);
        })
      } else {
        this[key] !== undefined && (json[key] = tryToJSON(this[key]))
      }
    })
    return json as T;
  }

  toString() {
    return JSON.stringify(this.toJson());
  }

  getUUID() {
    return this.uuid;
  }

  getName() {
    return this.name;
  }
}